<?php
namespace Icsoc\SecurityBundle\Security;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\SimpleFormAuthenticatorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class CustomerAuthenticator
 * @package Icsoc\SecurityBundle\Security
 */
class CustomerAuthenticator implements SimpleFormAuthenticatorInterface
{
    private $encoder;
    private $adminUser;
    private $container;

    /**
     * CustomerAuthenticator constructor.
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
        $this->encoder = $this->container->get("security.password_encoder");
    }

    /**
     * @param TokenInterface        $token
     * @param UserProviderInterface $userProvider
     * @param string                $providerKey
     * @return UsernamePasswordToken
     * @throws AuthenticationException
     */
    public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
    {
        $captcha = $this->container->get("request")->get("captcha");
        $key = $this->container->getParameter("gregwar_captcha.config.whitelist_key");
        if (!isset($this->container->get("session")->get($key)['phrase'])) {
            throw new AuthenticationException('Captcha error');
        }
        $phrase = $this->container->get("session")->get($key)['phrase'];//获取session中的值
        if (trim($captcha) != $phrase || empty($phrase)) {
            throw new AuthenticationException('Captcha error');
        }
        $check = array(
            "user_name" => $token->getUsername(),
            "admin_user" => $this->adminUser ? $this->adminUser : $token->getUser()->getAdminName(),
        );
        $user = $userProvider->loadUserByUsername($check);
        if (empty($user)) {
            throw new AuthenticationException('Invalid username');
        }
        $passwordValid = $this->encoder->isPasswordValid($user, $token->getCredentials());
        if ($passwordValid) {
            //再判断用户名是否一样
            /** @var \Icsoc\SecurityBundle\Entity\CcCcods $user */
            if ($user->getAdminName() != $this->adminUser) {
                throw new AuthenticationException('Invalid username');
            }
            switch ($user->getFlag()) {
                case 'ccod':
                    //从ccod 中登陆过来
                    if ($user->getStatus() != 1) {
                        throw new AuthenticationException('The account is not enabled');
                    }
                    break;
                case 'ccadmin':
                    // $providerKey = "admin"
                    break;
                case 'agent':
                    // $providerKey = "agent"
                    break;
            }
            $this->container->get('session')->set('login_vcc', $user->getUsername());
            $this->container->get('session')->set('login_user', $user->getAdminName());
            return new UsernamePasswordToken(
                $user,
                $user->getPassword(),
                $providerKey,
                $user->getRoles()
            );
        }
        throw new AuthenticationException('Invalid password');
    }

    /**
     * @param TokenInterface $token
     * @param string         $providerKey
     *
     * @return bool
     */
    public function supportsToken(TokenInterface $token, $providerKey)
    {
        return $token instanceof UsernamePasswordToken
        && $token->getProviderKey() === $providerKey;
    }

    /**
     * @param Request $request
     * @param string  $username
     * @param string  $password
     * @param string  $providerKey
     *
     * @return UsernamePasswordToken
     */
    public function createToken(Request $request, $username, $password, $providerKey)
    {
        $this->adminUser = $request->get("admin_user"); //从request 对象中获取；

        return new UsernamePasswordToken($username, $password, $providerKey);
    }
}
